package com.yunchao.library.lock

import kotlinx.coroutines.delay
import com.yunchao.library.lock.LockAction.CLOSE_LOCK
import com.yunchao.library.lock.LockAction.CLOSE_LOCK_LOGISTICS
import com.yunchao.library.lock.LockAction.OPEN_LOCK
import com.yunchao.library.lock.LockAction.OPEN_LOCK_LOGISTICS
import com.yunchao.library.lock.LockAction.RECOVERY_LOCK
import com.yunchao.library.lock.LockAction.CLEAR_LOCK_LOG
import com.yunchao.library.lock.LockAction.ACTIVATE_LOCK
import timber.log.Timber

private const val CLOSE_LOCK_HEAD_CMD = "80300200240C"
private const val OPEN_LOCK_HEAD_CMD = "80300300240C"
private const val CLOSE_LOCK_LOGISTICS_HEAD_CMD = "80300400240C"
private const val OPEN_LOCK_LOGISTICS_HEAD_CMD = "80300500240C"
private const val LOCK_LOG_HEAD_CMD = "80300600120C"
private const val RECOVERY_LOCK_HEAD_CMD = "80300700240C"
private const val CLEAR_LOCK_LOG_HEAD_CMD = "80300800210C"
private const val PASSWORD_LOCK_HEAD_CMD = "803600000C"
private const val ACTIVATE_LOCK_HEAD_CMD = "803001001C0C"
private const val AUTH_LOCK_HEAD_CMD = "803800001A0C"
private const val DECRYPTION_LOCK_HEAD_CMD = "80340600"

enum class LockAction(val cmd: String) {
    CLOSE_LOCK(CLOSE_LOCK_HEAD_CMD),
    OPEN_LOCK(OPEN_LOCK_HEAD_CMD),
    CLOSE_LOCK_LOGISTICS(CLOSE_LOCK_LOGISTICS_HEAD_CMD),
    OPEN_LOCK_LOGISTICS(OPEN_LOCK_LOGISTICS_HEAD_CMD),
    RECOVERY_LOCK(RECOVERY_LOCK_HEAD_CMD),
    CLEAR_LOCK_LOG(CLEAR_LOCK_LOG_HEAD_CMD),
    PASSWORD_LOCK(PASSWORD_LOCK_HEAD_CMD),
    ACTIVATE_LOCK(ACTIVATE_LOCK_HEAD_CMD),
    AUTH_LOCK(AUTH_LOCK_HEAD_CMD),
    DECRYPTION_LOCK(DECRYPTION_LOCK_HEAD_CMD),
    LOCK_LOG(LOCK_LOG_HEAD_CMD);
}


fun LockAction.getLockCmd(
    lockEPCInfo: LockEPCInfo,
    deviceId: Int,
    operatorId: Int,
    chkUserId: Int,
    pageNumber: Int,
    voucherType: String
): String = when (this) {
    CLOSE_LOCK -> getCloseLockCmdStr(
        lockEPCInfo.epc,
        deviceId,
        operatorId,
        chkUserId,
        pageNumber
    )

    OPEN_LOCK -> getOpenLockCmdStr(
        lockEPCInfo.epc,
        deviceId,
        operatorId,
        chkUserId,
        pageNumber
    )

    CLOSE_LOCK_LOGISTICS -> getCloseLockLogisticsCmdStr(
        lockEPCInfo.epc,
        deviceId,
        operatorId,
        chkUserId,
        pageNumber
    )

    OPEN_LOCK_LOGISTICS -> getOpenLockLogisticsCmdStr(
        lockEPCInfo.epc,
        deviceId,
        operatorId,
        chkUserId,
        pageNumber
    )

    RECOVERY_LOCK -> getRecoveryLockCmdStr(
        lockEPCInfo.epc,
        deviceId,
        operatorId,
        chkUserId,
        pageNumber
    )

    CLEAR_LOCK_LOG -> getClearLockCmdStr(
        lockEPCInfo.epc,
        deviceId,
        operatorId,
        chkUserId
    )

    ACTIVATE_LOCK -> getActivateLockCmdStr(
        lockEPCInfo.epc,
        voucherType = voucherType
    )

    else -> ""
}

suspend fun <T> retryCoroutine(
    attempts: Int = 3,
    delayTime: Long = 2000,  // 初始延迟（毫秒）
    block: suspend () -> T      // 执行的挂起函数
): T {
    repeat(attempts - 1) { attempt ->
        try {
            delay(delayTime)
            return block() // 尝试执行网
        } catch (e: Exception) {
            Timber.i("第 ${attempt + 1} 次尝试失败: ${e.message}")
        }
    }
    return block() // 最后一次尝试，如果失败则抛出异常
}




